knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE, cache = FALSE)

Load packages

library(Matrix) # my pc needs this to load the tidyverse correctly
library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(loo) # to use information criteria in brms models
library(dagitty) # to build DAGs
library(ggdag) # to tidy DAGs
library(tidybayes) # Bayesian aesthetics
library(MetBrewer) # colours
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(pander) # for simpler tables

Supplementary methods

\(~\)

Table S1. Recipe for food medium used in our experiment. The provided quantities make ~ 1 litre of food.

tibble("Ingredients" = c("Soy flour", "Cornmeal", "Yeast", "Dextrose", "Agar", "Water", "Tegosept", "Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL)"),
       "Quantity" = c("20 g", "73 g", "35 g", "75 g", "6 g", "1000 mL", "17 mL", "14 mL")) %>% 
  pander(split.cell = 40, split.table = Inf)
Ingredients Quantity
Soy flour 20 g
Cornmeal 73 g
Yeast 35 g
Dextrose 75 g
Agar 6 g
Water 1000 mL
Tegosept 17 mL
Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL) 14 mL

\(~\)

Load in the data

\(~\)

fitness_data <- read_csv("data/SLC_fitness_data.csv") %>% 
  mutate(Fitness_vial_ID = as.factor(Fitness_vial_ID),
         Block = as.factor(Block),
         Population = as.factor(Population),
         Treatment = as.factor(Treatment),
         GFP = as.factor(GFP),
         Sex = as.factor(Sex),
         Rearing_vial = as.factor(Rearing_vial),
         Total_red_offspring = Red_female_offspring + Red_male_offspring,
         Total_bw_offspring = bw_female_offspring + bw_male_offspring,
         Total_offspring = Total_red_offspring + Total_bw_offspring) %>% 
  rename(Inheritance_treatment = Treatment)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'fitness_data')),
      pageLength = 692
    )
  )
}


my_data_table(fitness_data %>% select(-Comment))

Column explanations

Fitness_vial_ID: a unique identifier for each trial of the fitness assay.

Block: the experiment was run in three distinct blocks, using flies from separate generations.

Population: we measured the fitness of flies from 12 independent populations that contained autosomes that had undergone experimental evolution.

Inheritance_treatment: the populations carried autosomes that had been exposed to one of three inheritance treatments for 20 generations: a female-limited inheritance treatment where autosomes were always passed from mother to daughter, a male-limited treatment where autosomes were passed from father to son, and a control condition where inheritance was unconstrained.

GFP: the GFP marker carried by the population. UBI indicates the presence of a transgene that encodes ubiquitous expression of GFP, while 3xP indicates the presence of a different transgene that encodes the expression of GFP in the ocelli.

Sex: the sex of the individuals that we were measuring the fitness of.

Rearing_vial: the vial the treatment flies used in the trial developed in. This variable is included to capture variation explained by the rearing environment e.g. small differences in food moisture content or quantity. Note that females and males can have the same rearing vial as the sexes were reared together.

Red_female_offspring: the number of adult female offspring sired/produced by flies sourced from one of the 12 populations.

Red_male_offspring: the number of adult male offspring sired/produced by flies sourced from one of the 12 populations.

bw_female_offspring: the number of adult female offspring sired/produced by the competitor flies in our fitness assay. bw is a recessive allele that encodes brown eye colour.

bw_male_offspring: the number of adult male offspring sired/produced by the competitor flies in our fitness assay. bw is a recessive allele that encodes brown eye colour.

Total_red_offspring: the total number (sexes pooled) of adult offspring sired/produced by flies sourced from one of the 12 populations.

Total_bw_offspring: the total number (sexes pooled) of adult offspring sired/produced by competitor flies.

Total_offspring: the total number (sexes and eye colours pooled) of adult offspring counted in each vial.

\(~\)

Modelling approach

\(~\)

Female and male fitness are fundamentally different concepts / traits. There are also several differences between our female and male fitness assays. The major difference is that the male assay contains half the number of females in any given vial than does the female assay. The logic behind this design choice is that sexually selected processes are a more important determinant of male fitness than they are female fitness, so any fitness differences may only be observed when competition for fertilisations is high.

For these reasons, we choose to split the data up and model female and male fitness separately.

female_fitness <- 
  fitness_data %>%
  filter(Sex == "Female")

male_fitness <- 
  fitness_data %>%
  filter(Sex == "Male") %>% 
  mutate(prop_red = Total_red_offspring / Total_offspring)

We fit the following fixed and random effects to model female and male fitness. Our aim is to estimate the causal effect that Inheritance_treatment (I) has on fitness (F).

The DAG below shows our understanding of the scientific question we are attempting to model. Arrows indicate the direction of causal effects, at least as we interpret them.

# Lets make a function to speed up the DAG making process

gg_simple_dag <- function(d) {
  
  d %>% 
    ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
    geom_dag_point(color = met.brewer("Hiroshige")[4]) +
    geom_dag_text(color = met.brewer("Hiroshige")[7]) +
    geom_dag_edges() + 
    theme_dag()
  
}

dag_coords <-
  tibble(name = c("I", "G", "B", "P", "R", "F"),
         x    = c(1, 1.5, 2.5, 1.5, 2.5, 2),
         y    = c(2, 3, 3, 1, 1, 2))

dagify(F ~ I + G + B + P + R,
       coords = dag_coords) %>%
  gg_simple_dag()

Fixed effects

Inheritance_treatment (I): this is the inheritance regime that the autosomes carried by each of the populations were subject to for 20 generations. There are three levels: populations carrying female-adapted autosomes, populations containing male-adapted autosomes and populations carrying control autosomes that experienced an unmanipulated inheritance regime. We are designing our model to test for a causal effect of this variable.

Mediator variables

Block (B): fitness might differ between the three distinct blocks we split our experiment up into. Blocks differed temporally, used flies from different generations and different batches of food. It is also possible that there were minor fluctuations in the lighting and temperature environment experienced during development between blocks. Each of these variables may introduce variation into our fitness measurements, that can be accounted for by including the Block variable in our model.

GFP (G): it is possible that fitness may be affected by the GFP transgene carried by each population. For example, one could imagine that any unintended fitness effects of a transgene might be of greater magnitude if it is expressed in a larger proportion of tissues, as is the case for the UBI transgene versus the 3xP transgene. Note that each GFP type is carried by an equal number of populations from each of the three evolutionary treatments.

Varying/Random effects

Population (P): our design contained 12 independent populations of autosomes that originated from a single outbred laboratory fly population. The populations were split and autosomes from each were subjected to one of the three evolution treatments for 20 generations. 4 populations experienced a female-limited inheritance regime, 4 a male-limited regime and 4 an unlimited or control regime.

Rearing_vial (R): the vial individual flies developed within may introduce further variation into our response variable. Like Block this variable controls for micro-environmental variation.

\(~\)

Accounting for over-dispersion

The data is over-dispersed with several highly influential (outlier) observations that have large effects on our posterior prediction. To combat this, we fit models following the betabinomial distribution family, as this is better equipped to deal with extreme values at the tails i.e. overdispersion.

However, the beta-binomial is not a native family in brms, we need to create the distribution family using the custom_family() function. The code below is taken directly from the brms_customfamilies vignette, which can be viewed here.

beta_binomial2 <- custom_family(
  "beta_binomial2", dpars = c("mu", "phi"),
  links = c("logit", "log"), lb = c(NA, 2), 
  # note that we set the lower bound to 2, following McElreath, rather than Buerkner. This means that the most conservative estimate for phi we get is a flat expectation between 0 and 1
  type = "int", vars = "vint1[n]"
)


stan_funs <- "
  real beta_binomial2_lpmf(int y, real mu, real phi, int T) {
    return beta_binomial_lpmf(y | T, mu * phi, (1 - mu) * phi);
  }
  int beta_binomial2_rng(real mu, real phi, int T) {
    return beta_binomial_rng(T, mu * phi, (1 - mu) * phi);
  }
"

stanvars <- stanvar(scode = stan_funs, block = "functions")

\(~\)

Female fitness

\(~\)

To estimate the fitness of females carrying each of the three autosome types, we placed three experimental females into a yeasted vial with three female competitors that carried the bw mutation. We then introduced six males that also carried the bw mutation. We allowed them to mate and oviposit for three days, then removed all adults from the vial. 12 days later we counted all of the adult progeny in the vial and scored them for eye-colour. Progeny with red eyes were produced by the experimental females ( bw is recessive) and progeny with brown eyes were produced by the competitor females. We calculated fitness as the proportion of red eyed offspring in the vial.

We present the fixed effects from the model:

\(~\)

female_fitness_model <-
  brm(Total_red_offspring | vint(Total_offspring) ~ 1 + Inheritance_treatment + Block + GFP + (1|Population) + (1|Rearing_vial),
      data = female_fitness, family = beta_binomial2, 
      prior = c(prior(normal(0, 1), class = Intercept),
                prior(normal(0, 1.5), class = b),
                prior(exponential(1), class = phi)),
      iter = 4000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.95, max_treedepth = 10),
      seed = 2, stanvars = stanvars, file = "Fits/female_fitness.model")

fixef(female_fitness_model) %>% 
  kable(digits = 3) %>% 
  kable_styling()
Estimate Est.Error Q2.5 Q97.5
Intercept 1.112 0.095 0.920 1.300
Inheritance_treatmentFemale_limited 0.168 0.104 -0.050 0.376
Inheritance_treatmentMale_limited 0.185 0.103 -0.018 0.388
Block2 -0.637 0.081 -0.793 -0.477
Block3 -0.624 0.072 -0.765 -0.483
GFPUBI -0.322 0.085 -0.489 -0.154

We need to write some additional code to get some post processing stuff i.e. LOO to work. Code courtesy of the brms_customfamilies vignette, which can be viewed here.

Run LOO to see if we’ve effectively modelled over dispersion.

female_fitness_model <- add_criterion(female_fitness_model, criterion = "loo", file = "Fits/female_fitness.model")

loo(female_fitness_model)
## 
## Computed from 8000 by 327 log-likelihood matrix
## 
##          Estimate   SE
## elpd_loo  -1399.9 10.6
## p_loo        23.0  2.1
## looic      2799.8 21.3
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     326   99.7%   2845      
##  (0.5, 0.7]   (ok)         1    0.3%   1130      
##    (0.7, 1]   (bad)        0    0.0%   <NA>      
##    (1, Inf)   (very bad)   0    0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.

The beta-binomial model looks good. It returns no points with high pareto k values.

Conduct a posterior predictive check to confirm our model is doing what we want it to.

pp_check(female_fitness_model, type = "hist", ndraws = 11, binwidth = 10) +
  theme_minimal() +
  theme(panel.background = element_blank())

The posterior predictive distribution matches our raw data quite well, indicating the model is functioning as we wanted.

\(~\)

Derive predictions from the posterior

Get predictions from the model and present them in a Table

draws <- as_draws_df(female_fitness_model)

draws_female <-
  draws  %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>% 
  select(`Female-limited`, Control, `Male-limited`) %>% 
    pivot_longer(cols = c(`Female-limited`, Control, `Male-limited`),
                 names_to = "Inheritance_treatment") %>% 
  rename(prop_focal_offspring = value) %>% 
  arrange(Inheritance_treatment)

draws_diff <- draws  %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>%
  mutate(`Female - Control` = `Female-limited` - Control,
         `Male - Control` = `Male-limited` - Control,
         `Female - Male` = `Female-limited` - `Male-limited`) %>% 
  select(`Female - Control`, `Male - Control`, `Female - Male`)

 #draws_diff %>% 
  # summarise(`Estimated prop. of offspring produced` = mean(`Male - Control`)*100,
   #         `2.5%` = quantile(`Male - Control`, probs = 0.025) *100,
    #        `97.5%` = quantile(`Male - Control`, probs = 0.975) *100)

draws_female %>% 
  group_by(Inheritance_treatment) %>% 
  summarise(`Estimated prop. of offspring produced` = mean(prop_focal_offspring),
            `2.5%` = quantile(prop_focal_offspring, probs = 0.025),
            `97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Inheritance_treatment Estimated prop. of offspring produced 2.5% 97.5%
Control 0.752 0.715 0.786
Female-limited 0.782 0.747 0.812
Male-limited 0.785 0.753 0.814
# now find the differences between the control and the sex-limited treatments

# the inv_logit_scaled() function converts the posterior draws onto the response scale 

prop_table_female <-
  draws %>% 
  mutate(p_control =  inv_logit_scaled(b_Intercept),
         p_female = inv_logit_scaled(b_Inheritance_treatmentFemale_limited + b_Intercept),
         p_male = inv_logit_scaled(b_Inheritance_treatmentMale_limited + b_Intercept),
         `Female-limited` = p_female / p_control,
         `Male-limited` = p_male / p_control) %>% 
  gather(key = `difference comparison`, value = `% difference`) %>% 
  filter(`difference comparison` == c("Female-limited", "Male-limited")) %>% 
  group_by(`difference comparison`)  %>% 
  summarise(`Mean proportion of offspring produced relative to control`  = mean(`% difference`),
            `2.5%` = quantile(`% difference`, probs = 0.025),
            `97.5%` = quantile(`% difference`, probs = 0.975)) %>% 
  rename(`Inheritance treatment` = `difference comparison`) #%>% 
#pander(split.cell = 40, split.table = Inf, round = 3)

\(~\)

Male fitness

\(~\)

To estimate the fitness of males carrying each of the three chromosome types, we conducted an experiment very similar to the female fitness assay. However, because male fitness has stronger covariance with fertilisation events than does female fitness, we conducted the male fitness assay with a 1:2 sex ratio (female:male) rather than the 1:1 ratio used in the female assay. This increases the strength of sexual selection and is a more appropriate way to expose differences in fitness between groups of males. As with the females, we calculated fitness as the proportion of red-eyed offspring in the vial.

male_fitness_model <-
  brm(Total_red_offspring | vint(Total_offspring) ~ 1 + Inheritance_treatment + Block + GFP + (1|Population) + (1|Rearing_vial),
      data = male_fitness, family = beta_binomial2, 
      prior = c(prior(normal(0, 1), class = Intercept),
                prior(normal(0, 1.5), class = b),
                prior(exponential(1), class = phi)),
      iter = 4000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.95, max_treedepth = 10),
      seed = 2, stanvars = stanvars, file = "Fits/male_fitness.model")


fixef(male_fitness_model) %>% 
  kable(digits = 3) %>% 
  kable_styling()
Estimate Est.Error Q2.5 Q97.5
Intercept 0.765 0.233 0.299 1.221
Inheritance_treatmentFemale_limited 0.417 0.268 -0.133 0.946
Inheritance_treatmentMale_limited 0.105 0.266 -0.430 0.631
Block2 0.970 0.149 0.670 1.265
Block3 -0.034 0.142 -0.304 0.247
GFPUBI -0.336 0.226 -0.786 0.117

Run LOO to see if we’ve effectively modelled over dispersion.

male_fitness_model <- add_criterion(male_fitness_model, criterion = "loo", file = "Fits/male_fitness.model")

loo(male_fitness_model)
## 
## Computed from 8000 by 360 log-likelihood matrix
## 
##          Estimate   SE
## elpd_loo  -1561.9 21.4
## p_loo        23.3  1.9
## looic      3123.8 42.8
## ------
## Monte Carlo SE of elpd_loo is NA.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     359   99.7%   2275      
##  (0.5, 0.7]   (ok)         0    0.0%   <NA>      
##    (0.7, 1]   (bad)        0    0.0%   <NA>      
##    (1, Inf)   (very bad)   1    0.3%   4000      
## See help('pareto-k-diagnostic') for details.

There is one point having a large effect on the posterior. Upon inspection, this data point is not an unreasonable one and there is no cause to remove it from the dataset. It also does not change the causal effect of inheritance treatment on male fitness.

Conduct the posterior predictive check…

pp_check(male_fitness_model, type = "hist", ndraws = 11, binwidth = 10) +
  theme_minimal() +
  theme(panel.background = element_blank())

Derive estimates from posterior

Get predictions from the model and present them in a Table

# predictions for block 1, with UBI GFP

new_data <- tibble(Inheritance_treatment = male_fitness$Inheritance_treatment) %>% 
  distinct(Inheritance_treatment) %>% 
  mutate(Population = 1,
         Block = 1,
         Rearing_vial = 1,
         GFP = "UBI",
         Total_offspring = 1)

predictions_male <- fitted(male_fitness_model, newdata = new_data)

predictions_male <- cbind(new_data, predictions_male)


table1 <-
  predictions_male %>% 
  select(-c(Population, Rearing_vial, GFP, Total_offspring)) %>%
  arrange(Block) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)

draws_m <- as_draws_df(male_fitness_model)

# predictions averaged over mediator variables

draws_male <-
  draws_m  %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>% 
  select(Control, `Female-limited`, `Male-limited`) %>% 
    pivot_longer(cols = c(Control, `Female-limited`, `Male-limited`),
                 names_to = "Inheritance_treatment") %>% 
  rename(prop_focal_offspring = value)

draws_diff_m <- draws_m %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Inheritance_treatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>%
  mutate(`Female - Control` = `Female-limited` - Control,
         `Male - Control` = `Male-limited` - Control,
         `Female - Male` = `Female-limited` - `Male-limited`) %>% 
  select(`Female - Control`, `Male - Control`, `Female - Male`)

# actual Table 1

draws_male %>% 
  group_by(Inheritance_treatment) %>% 
  summarise(`Estimated prop. of offspring sired` = mean(prop_focal_offspring),
            `2.5%` = quantile(prop_focal_offspring, probs = 0.025),
            `97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Inheritance_treatment Estimated prop. of offspring sired 2.5% 97.5%
Control 0.68 0.574 0.772
Female-limited 0.762 0.662 0.841
Male-limited 0.702 0.594 0.794
# now find the differences between the control and the sex-limited Evolution_treatments

# the inv_logit_scaled() function converts the posterior draws onto the response scale 

prop_table_male <- 
  draws_m %>% 
  mutate(p_control =  inv_logit_scaled(b_Intercept),
         p_female = inv_logit_scaled(b_Inheritance_treatmentFemale_limited + b_Intercept),
         p_male = inv_logit_scaled(b_Inheritance_treatmentMale_limited + b_Intercept),
         `Female-limited` = p_female / p_control,
         `Male-limited` = p_male / p_control) %>% 
  gather(key = `difference comparison`, value = `% difference`) %>% 
  filter(`difference comparison` == c("Female-limited", "Male-limited")) %>% 
  group_by(`difference comparison`)  %>% 
  summarise(`Mean proportion of offspring sired relative to control`  = mean(`% difference`),
            `2.5%` = quantile(`% difference`, probs = 0.025),
            `97.5%` = quantile(`% difference`, probs = 0.975)) %>% 
  rename(`Inheritance treatment` = `difference comparison`) #%>% 
  #pander(split.cell = 40, split.table = Inf, round = 3)

Building Figure 2

# female plots

f_1 <-
  draws_female %>% 
  mutate(Inheritance_treatment = fct_relevel(Inheritance_treatment, "Female-limited", "Control", "Male-limited")) %>% 
  ggplot(aes(Inheritance_treatment, prop_focal_offspring)) + 
  stat_halfeye(aes(fill = Inheritance_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5) + # width indicates the uncertainty intervals: we have 66% and 95% intervals
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  coord_flip() +
  xlab("Inheritance treatment") +
  ylab("Female fitness\n(prop. offspring produced)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

f_2 <-
  draws_diff %>% 
  gather(key = parameter, value = `Fitness difference`) %>% 
  as_tibble() %>%   

  ggplot(aes(parameter, `Fitness difference`)) + 
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9, point_interval = "mean_qi",
               slab_fill = met.brewer("Hiroshige")[1],
               shape = 21, point_size = 3, stroke = 1.5,
               point_fill = "white") + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  coord_flip() +
  geom_hline(yintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Treatment contrast") +
  ylab("Female fitness difference\n(prop. offspring produced)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

# male plots

f_3 <-
  draws_male %>% 
  mutate(Inheritance_treatment = fct_relevel(Inheritance_treatment, "Female-limited", "Control", "Male-limited")) %>% 
  ggplot(aes(Inheritance_treatment, prop_focal_offspring)) + 
   stat_halfeye(aes(fill = Inheritance_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  coord_flip() +
  xlab("Inheritance treatment") +
  ylab("Male fitness\n(prop. offspring produced)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

f_4 <-
  draws_diff_m %>%
  gather(key = parameter, value = `Fitness difference`) %>% 
  as_tibble() %>% 
  ggplot(aes(parameter, `Fitness difference`)) + 
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9, point_interval = "mean_qi",
               slab_fill = met.brewer("Hiroshige")[1],
               shape = 21, point_size = 3, stroke = 1.5,
               point_fill = "white") + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = met.brewer("Hokusai3", 3)) +
  coord_flip() +
  geom_hline(yintercept = 0, linetype = 2) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  xlab("Treatment contrast") +
  ylab("Male fitness difference\n(prop. offspring sired)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())


(f_1 + f_2) /(f_3 + f_4) + 
  plot_annotation(tag_levels = 'a')

Figure 2: a shows the estimated distribution of the mean for female fitness for flies carrying autosomes that had previously experienced unconstrained inheritance (control), female-limited inheritance or male-limited inheritance. b shows the difference contrast in female fitness between each of the three inheritance treatments. This difference is on the proportion scale, where a value of 0.1 indicates that females of a given inheritance treatment produce 10 more offspring per every 100 when cohabiting with bw competitor females. c and d depict the same things as a and b, except for male fitness.

LS0tCnRpdGxlOiAiRXhwZXJpbWVudGFsIGVuZm9yY2VtZW50IG9mIHNleC1saW1pdGVkIGF1dG9zb21lIGluaGVyaXRhbmNlIGRvZXMgbm90IHJldmVhbCBpbnRyYWxvY3VzIHNleHVhbCBjb25mbGljdCIKYXV0aG9yOiAiVGhvbWFzIEtlYW5leSwgSGVpZGkgV29uZywgVGhlcmVzYSBKb25lcyBhbmQgTHVrZSBIb2xtYW4iCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGVwdGg6IDEKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgoKCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBjYWNoZSA9IEZBTFNFKQpgYGAKCiMgTG9hZCBwYWNrYWdlcwoKYGBge3J9CmxpYnJhcnkoTWF0cml4KSAjIG15IHBjIG5lZWRzIHRoaXMgdG8gbG9hZCB0aGUgdGlkeXZlcnNlIGNvcnJlY3RseQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IHN0eWxlIGNvZGluZwpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzCmxpYnJhcnkobG9vKSAjIHRvIHVzZSBpbmZvcm1hdGlvbiBjcml0ZXJpYSBpbiBicm1zIG1vZGVscwpsaWJyYXJ5KGRhZ2l0dHkpICMgdG8gYnVpbGQgREFHcwpsaWJyYXJ5KGdnZGFnKSAjIHRvIHRpZHkgREFHcwpsaWJyYXJ5KHRpZHliYXllcykgIyBCYXllc2lhbiBhZXN0aGV0aWNzCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMKbGlicmFyeShrYWJsZUV4dHJhKSAjIHRhYmxlcwpsaWJyYXJ5KHBhdGNod29yaykgIyBwdXR0aW5nIHBsb3RzIHRvZ2V0aGVyCmxpYnJhcnkoRFQpICMgZm9yIHNlYXJjaC0gYW5kIHNhdmVhYmxlIHRhYmxlcwpsaWJyYXJ5KHBhbmRlcikgIyBmb3Igc2ltcGxlciB0YWJsZXMKCmBgYAoKIyBTdXBwbGVtZW50YXJ5IG1ldGhvZHMKCiR+JAoKKipUYWJsZSBTMSoqLiBSZWNpcGUgZm9yIGZvb2QgbWVkaXVtIHVzZWQgaW4gb3VyIGV4cGVyaW1lbnQuIFRoZSBwcm92aWRlZCBxdWFudGl0aWVzIG1ha2UgfiAxIGxpdHJlIG9mIGZvb2QuCgpgYGB7cn0KdGliYmxlKCJJbmdyZWRpZW50cyIgPSBjKCJTb3kgZmxvdXIiLCAiQ29ybm1lYWwiLCAiWWVhc3QiLCAiRGV4dHJvc2UiLCAiQWdhciIsICJXYXRlciIsICJUZWdvc2VwdCIsICJBY2lkIG1peCAoNCBtTCBvcnRob3Bob3NwaG9yaWMgYWNpZCwgNDEgbUwgcHJvcGlvbmljIGFjaWQsIDU1IG1MIHdhdGVyIHRvIG1ha2UgMTAwIG1MKSIpLAogICAgICAgIlF1YW50aXR5IiA9IGMoIjIwIGciLCAiNzMgZyIsICIzNSBnIiwgIjc1IGciLCAiNiBnIiwgIjEwMDAgbUwiLCAiMTcgbUwiLCAiMTQgbUwiKSkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mKQpgYGAKCiR+JAoKIyBMb2FkIGluIHRoZSBkYXRhIAoKJH4kCgpgYGB7cn0KCmZpdG5lc3NfZGF0YSA8LSByZWFkX2NzdigiZGF0YS9TTENfZml0bmVzc19kYXRhLmNzdiIpICU+JSAKICBtdXRhdGUoRml0bmVzc192aWFsX0lEID0gYXMuZmFjdG9yKEZpdG5lc3NfdmlhbF9JRCksCiAgICAgICAgIEJsb2NrID0gYXMuZmFjdG9yKEJsb2NrKSwKICAgICAgICAgUG9wdWxhdGlvbiA9IGFzLmZhY3RvcihQb3B1bGF0aW9uKSwKICAgICAgICAgVHJlYXRtZW50ID0gYXMuZmFjdG9yKFRyZWF0bWVudCksCiAgICAgICAgIEdGUCA9IGFzLmZhY3RvcihHRlApLAogICAgICAgICBTZXggPSBhcy5mYWN0b3IoU2V4KSwKICAgICAgICAgUmVhcmluZ192aWFsID0gYXMuZmFjdG9yKFJlYXJpbmdfdmlhbCksCiAgICAgICAgIFRvdGFsX3JlZF9vZmZzcHJpbmcgPSBSZWRfZmVtYWxlX29mZnNwcmluZyArIFJlZF9tYWxlX29mZnNwcmluZywKICAgICAgICAgVG90YWxfYndfb2Zmc3ByaW5nID0gYndfZmVtYWxlX29mZnNwcmluZyArIGJ3X21hbGVfb2Zmc3ByaW5nLAogICAgICAgICBUb3RhbF9vZmZzcHJpbmcgPSBUb3RhbF9yZWRfb2Zmc3ByaW5nICsgVG90YWxfYndfb2Zmc3ByaW5nKSAlPiUgCiAgcmVuYW1lKEluaGVyaXRhbmNlX3RyZWF0bWVudCA9IFRyZWF0bWVudCkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnZml0bmVzc19kYXRhJykpLAogICAgICBwYWdlTGVuZ3RoID0gNjkyCiAgICApCiAgKQp9CgoKbXlfZGF0YV90YWJsZShmaXRuZXNzX2RhdGEgJT4lIHNlbGVjdCgtQ29tbWVudCkpCgpgYGAKCioqQ29sdW1uIGV4cGxhbmF0aW9ucyoqCgpGaXRuZXNzX3ZpYWxfSUQ6IGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGVhY2ggdHJpYWwgb2YgdGhlIGZpdG5lc3MgYXNzYXkuCgpCbG9jazogdGhlIGV4cGVyaW1lbnQgd2FzIHJ1biBpbiB0aHJlZSBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIGZyb20gc2VwYXJhdGUgZ2VuZXJhdGlvbnMuCgpQb3B1bGF0aW9uOiB3ZSBtZWFzdXJlZCB0aGUgZml0bmVzcyBvZiBmbGllcyBmcm9tIDEyIGluZGVwZW5kZW50IHBvcHVsYXRpb25zIHRoYXQgY29udGFpbmVkIGF1dG9zb21lcyB0aGF0IGhhZCB1bmRlcmdvbmUgZXhwZXJpbWVudGFsIGV2b2x1dGlvbi4KCkluaGVyaXRhbmNlX3RyZWF0bWVudDogdGhlIHBvcHVsYXRpb25zIGNhcnJpZWQgYXV0b3NvbWVzIHRoYXQgaGFkIGJlZW4gZXhwb3NlZCB0byBvbmUgb2YgdGhyZWUgaW5oZXJpdGFuY2UgdHJlYXRtZW50cyBmb3IgMjAgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgaW5oZXJpdGFuY2UgdHJlYXRtZW50IHdoZXJlIGF1dG9zb21lcyB3ZXJlIGFsd2F5cyBwYXNzZWQgZnJvbSBtb3RoZXIgdG8gZGF1Z2h0ZXIsIGEgbWFsZS1saW1pdGVkIHRyZWF0bWVudCB3aGVyZSBhdXRvc29tZXMgd2VyZSBwYXNzZWQgZnJvbSBmYXRoZXIgdG8gc29uLCBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBpbmhlcml0YW5jZSB3YXMgdW5jb25zdHJhaW5lZC4KCkdGUDogdGhlIEdGUCBtYXJrZXIgY2FycmllZCBieSB0aGUgcG9wdWxhdGlvbi4gVUJJIGluZGljYXRlcyB0aGUgcHJlc2VuY2Ugb2YgYSB0cmFuc2dlbmUgdGhhdCBlbmNvZGVzIHViaXF1aXRvdXMgZXhwcmVzc2lvbiBvZiBHRlAsIHdoaWxlIDN4UCBpbmRpY2F0ZXMgdGhlIHByZXNlbmNlIG9mIGEgZGlmZmVyZW50IHRyYW5zZ2VuZSB0aGF0IGVuY29kZXMgdGhlIGV4cHJlc3Npb24gb2YgR0ZQIGluIHRoZSBvY2VsbGkuIAoKU2V4OiB0aGUgc2V4IG9mIHRoZSBpbmRpdmlkdWFscyB0aGF0IHdlIHdlcmUgbWVhc3VyaW5nIHRoZSBmaXRuZXNzIG9mLgoKUmVhcmluZ192aWFsOiB0aGUgdmlhbCB0aGUgdHJlYXRtZW50IGZsaWVzIHVzZWQgaW4gdGhlIHRyaWFsIGRldmVsb3BlZCBpbi4gVGhpcyB2YXJpYWJsZSBpcyBpbmNsdWRlZCB0byBjYXB0dXJlIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIHJlYXJpbmcgZW52aXJvbm1lbnQgZS5nLiBzbWFsbCBkaWZmZXJlbmNlcyBpbiBmb29kIG1vaXN0dXJlIGNvbnRlbnQgb3IgcXVhbnRpdHkuIE5vdGUgdGhhdCBmZW1hbGVzIGFuZCBtYWxlcyBjYW4gaGF2ZSB0aGUgc2FtZSByZWFyaW5nIHZpYWwgYXMgdGhlIHNleGVzIHdlcmUgcmVhcmVkIHRvZ2V0aGVyLgoKUmVkX2ZlbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KClJlZF9tYWxlX29mZnNwcmluZzogdGhlIG51bWJlciBvZiBhZHVsdCBtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KCmJ3X2ZlbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmbGllcyBpbiBvdXIgZml0bmVzcyBhc3NheS4gX2J3XyBpcyBhIHJlY2Vzc2l2ZSBhbGxlbGUgdGhhdCBlbmNvZGVzIGJyb3duIGV5ZSBjb2xvdXIuCgpid19tYWxlX29mZnNwcmluZzogdGhlIG51bWJlciBvZiBhZHVsdCBtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmbGllcyBpbiBvdXIgZml0bmVzcyBhc3NheS4gX2J3XyBpcyBhIHJlY2Vzc2l2ZSBhbGxlbGUgdGhhdCBlbmNvZGVzIGJyb3duIGV5ZSBjb2xvdXIuCgpUb3RhbF9yZWRfb2Zmc3ByaW5nOiB0aGUgdG90YWwgbnVtYmVyIChzZXhlcyBwb29sZWQpIG9mIGFkdWx0IG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSBmbGllcyBzb3VyY2VkIGZyb20gb25lIG9mIHRoZSAxMiBwb3B1bGF0aW9ucy4KClRvdGFsX2J3X29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgcG9vbGVkKSBvZiBhZHVsdCBvZmZzcHJpbmcgc2lyZWQvcHJvZHVjZWQgYnkgY29tcGV0aXRvciBmbGllcy4KClRvdGFsX29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgYW5kIGV5ZSBjb2xvdXJzIHBvb2xlZCkgb2YgYWR1bHQgb2Zmc3ByaW5nIGNvdW50ZWQgaW4gZWFjaCB2aWFsLgoKCiR+JAoKIyBNb2RlbGxpbmcgYXBwcm9hY2gKCiR+JAoKRmVtYWxlIGFuZCBtYWxlIGZpdG5lc3MgYXJlIGZ1bmRhbWVudGFsbHkgZGlmZmVyZW50IGNvbmNlcHRzIC8gdHJhaXRzLiBUaGVyZSBhcmUgYWxzbyBzZXZlcmFsIGRpZmZlcmVuY2VzIGJldHdlZW4gb3VyIGZlbWFsZSBhbmQgbWFsZSBmaXRuZXNzIGFzc2F5cy4gVGhlIG1ham9yIGRpZmZlcmVuY2UgaXMgdGhhdCB0aGUgbWFsZSBhc3NheSBjb250YWlucyBoYWxmIHRoZSBudW1iZXIgb2YgZmVtYWxlcyBpbiBhbnkgZ2l2ZW4gdmlhbCB0aGFuIGRvZXMgdGhlIGZlbWFsZSBhc3NheS4gVGhlIGxvZ2ljIGJlaGluZCB0aGlzIGRlc2lnbiBjaG9pY2UgaXMgdGhhdCBzZXh1YWxseSBzZWxlY3RlZCBwcm9jZXNzZXMgYXJlIGEgbW9yZSBpbXBvcnRhbnQgZGV0ZXJtaW5hbnQgb2YgbWFsZSBmaXRuZXNzIHRoYW4gdGhleSBhcmUgZmVtYWxlIGZpdG5lc3MsIHNvIGFueSBmaXRuZXNzIGRpZmZlcmVuY2VzIG1heSBvbmx5IGJlIG9ic2VydmVkIHdoZW4gY29tcGV0aXRpb24gZm9yIGZlcnRpbGlzYXRpb25zIGlzIGhpZ2guIAoKRm9yIHRoZXNlIHJlYXNvbnMsIHdlIGNob29zZSB0byBzcGxpdCB0aGUgZGF0YSB1cCBhbmQgbW9kZWwgZmVtYWxlIGFuZCBtYWxlIGZpdG5lc3Mgc2VwYXJhdGVseS4KCmBgYHtyfQpmZW1hbGVfZml0bmVzcyA8LSAKICBmaXRuZXNzX2RhdGEgJT4lCiAgZmlsdGVyKFNleCA9PSAiRmVtYWxlIikKCm1hbGVfZml0bmVzcyA8LSAKICBmaXRuZXNzX2RhdGEgJT4lCiAgZmlsdGVyKFNleCA9PSAiTWFsZSIpICU+JSAKICBtdXRhdGUocHJvcF9yZWQgPSBUb3RhbF9yZWRfb2Zmc3ByaW5nIC8gVG90YWxfb2Zmc3ByaW5nKQogIApgYGAKCldlIGZpdCB0aGUgZm9sbG93aW5nIGZpeGVkIGFuZCByYW5kb20gZWZmZWN0cyB0byBtb2RlbCBmZW1hbGUgYW5kIG1hbGUgZml0bmVzcy4gT3VyIGFpbSBpcyB0byBlc3RpbWF0ZSB0aGUgY2F1c2FsIGVmZmVjdCB0aGF0IGBJbmhlcml0YW5jZV90cmVhdG1lbnQgKEkpYCBoYXMgb24gYGZpdG5lc3MgKEYpYC4KClRoZSBEQUcgYmVsb3cgc2hvd3Mgb3VyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHNjaWVudGlmaWMgcXVlc3Rpb24gd2UgYXJlIGF0dGVtcHRpbmcgdG8gbW9kZWwuIEFycm93cyBpbmRpY2F0ZSB0aGUgZGlyZWN0aW9uIG9mIGNhdXNhbCBlZmZlY3RzLCBhdCBsZWFzdCBhcyB3ZSBpbnRlcnByZXQgdGhlbS4gCgpgYGB7cn0KIyBMZXRzIG1ha2UgYSBmdW5jdGlvbiB0byBzcGVlZCB1cCB0aGUgREFHIG1ha2luZyBwcm9jZXNzCgpnZ19zaW1wbGVfZGFnIDwtIGZ1bmN0aW9uKGQpIHsKICAKICBkICU+JSAKICAgIGdncGxvdChhZXMoeCA9IHgsIHkgPSB5LCB4ZW5kID0geGVuZCwgeWVuZCA9IHllbmQpKSArCiAgICBnZW9tX2RhZ19wb2ludChjb2xvciA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzRdKSArCiAgICBnZW9tX2RhZ190ZXh0KGNvbG9yID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIilbN10pICsKICAgIGdlb21fZGFnX2VkZ2VzKCkgKyAKICAgIHRoZW1lX2RhZygpCiAgCn0KCmRhZ19jb29yZHMgPC0KICB0aWJibGUobmFtZSA9IGMoIkkiLCAiRyIsICJCIiwgIlAiLCAiUiIsICJGIiksCiAgICAgICAgIHggICAgPSBjKDEsIDEuNSwgMi41LCAxLjUsIDIuNSwgMiksCiAgICAgICAgIHkgICAgPSBjKDIsIDMsIDMsIDEsIDEsIDIpKQoKZGFnaWZ5KEYgfiBJICsgRyArIEIgKyBQICsgUiwKICAgICAgIGNvb3JkcyA9IGRhZ19jb29yZHMpICU+JQogIGdnX3NpbXBsZV9kYWcoKQoKCmBgYAoKKipGaXhlZCBlZmZlY3RzKioKCmBJbmhlcml0YW5jZV90cmVhdG1lbnQgKEkpYDogdGhpcyBpcyB0aGUgaW5oZXJpdGFuY2UgcmVnaW1lIHRoYXQgdGhlIGF1dG9zb21lcyBjYXJyaWVkIGJ5IGVhY2ggb2YgdGhlIHBvcHVsYXRpb25zIHdlcmUgc3ViamVjdCB0byBmb3IgMjAgZ2VuZXJhdGlvbnMuIFRoZXJlIGFyZSB0aHJlZSBsZXZlbHM6IHBvcHVsYXRpb25zIGNhcnJ5aW5nIGZlbWFsZS1hZGFwdGVkIGF1dG9zb21lcywgcG9wdWxhdGlvbnMgY29udGFpbmluZyBtYWxlLWFkYXB0ZWQgYXV0b3NvbWVzIGFuZCBwb3B1bGF0aW9ucyBjYXJyeWluZyBjb250cm9sIGF1dG9zb21lcyB0aGF0IGV4cGVyaWVuY2VkIGFuIHVubWFuaXB1bGF0ZWQgaW5oZXJpdGFuY2UgcmVnaW1lLiBXZSBhcmUgZGVzaWduaW5nIG91ciBtb2RlbCB0byB0ZXN0IGZvciBhIGNhdXNhbCBlZmZlY3Qgb2YgdGhpcyB2YXJpYWJsZS4KCl9NZWRpYXRvciB2YXJpYWJsZXNfCgpgQmxvY2sgKEIpYDogZml0bmVzcyBtaWdodCBkaWZmZXIgYmV0d2VlbiB0aGUgdGhyZWUgZGlzdGluY3QgYmxvY2tzIHdlIHNwbGl0IG91ciBleHBlcmltZW50IHVwIGludG8uIEJsb2NrcyBkaWZmZXJlZCB0ZW1wb3JhbGx5LCB1c2VkIGZsaWVzIGZyb20gZGlmZmVyZW50IGdlbmVyYXRpb25zIGFuZCBkaWZmZXJlbnQgYmF0Y2hlcyBvZiBmb29kLiBJdCBpcyBhbHNvIHBvc3NpYmxlIHRoYXQgdGhlcmUgd2VyZSBtaW5vciBmbHVjdHVhdGlvbnMgaW4gdGhlIGxpZ2h0aW5nIGFuZCB0ZW1wZXJhdHVyZSBlbnZpcm9ubWVudCBleHBlcmllbmNlZCBkdXJpbmcgZGV2ZWxvcG1lbnQgYmV0d2VlbiBibG9ja3MuIEVhY2ggb2YgdGhlc2UgdmFyaWFibGVzIG1heSBpbnRyb2R1Y2UgdmFyaWF0aW9uIGludG8gb3VyIGZpdG5lc3MgbWVhc3VyZW1lbnRzLCB0aGF0IGNhbiBiZSBhY2NvdW50ZWQgZm9yIGJ5IGluY2x1ZGluZyB0aGUgYEJsb2NrYCB2YXJpYWJsZSBpbiBvdXIgbW9kZWwuCgpgR0ZQIChHKWA6IGl0IGlzIHBvc3NpYmxlIHRoYXQgZml0bmVzcyBtYXkgYmUgYWZmZWN0ZWQgYnkgdGhlIEdGUCB0cmFuc2dlbmUgY2FycmllZCBieSBlYWNoIHBvcHVsYXRpb24uIEZvciBleGFtcGxlLCBvbmUgY291bGQgaW1hZ2luZSB0aGF0IGFueSB1bmludGVuZGVkIGZpdG5lc3MgZWZmZWN0cyBvZiBhIHRyYW5zZ2VuZSBtaWdodCBiZSBvZiBncmVhdGVyIG1hZ25pdHVkZSBpZiBpdCBpcyBleHByZXNzZWQgaW4gYSBsYXJnZXIgcHJvcG9ydGlvbiBvZiB0aXNzdWVzLCBhcyBpcyB0aGUgY2FzZSBmb3IgdGhlIF9VQklfIHRyYW5zZ2VuZSB2ZXJzdXMgdGhlIF8zeFBfIHRyYW5zZ2VuZS4gTm90ZSB0aGF0IGVhY2ggR0ZQIHR5cGUgaXMgY2FycmllZCBieSBhbiBlcXVhbCBudW1iZXIgb2YgcG9wdWxhdGlvbnMgZnJvbSBlYWNoIG9mIHRoZSB0aHJlZSBldm9sdXRpb25hcnkgdHJlYXRtZW50cy4KCioqVmFyeWluZy9SYW5kb20gZWZmZWN0cyoqCgpgUG9wdWxhdGlvbiAoUClgOiBvdXIgZGVzaWduIGNvbnRhaW5lZCAxMiBpbmRlcGVuZGVudCBwb3B1bGF0aW9ucyBvZiBhdXRvc29tZXMgdGhhdCBvcmlnaW5hdGVkIGZyb20gYSBzaW5nbGUgb3V0YnJlZCBsYWJvcmF0b3J5IGZseSBwb3B1bGF0aW9uLiBUaGUgcG9wdWxhdGlvbnMgd2VyZSBzcGxpdCBhbmQgYXV0b3NvbWVzIGZyb20gZWFjaCB3ZXJlIHN1YmplY3RlZCB0byBvbmUgb2YgdGhlIHRocmVlIGV2b2x1dGlvbiB0cmVhdG1lbnRzIGZvciAyMCBnZW5lcmF0aW9ucy4gNCBwb3B1bGF0aW9ucyBleHBlcmllbmNlZCBhIGZlbWFsZS1saW1pdGVkIGluaGVyaXRhbmNlIHJlZ2ltZSwgNCBhIG1hbGUtbGltaXRlZCByZWdpbWUgYW5kIDQgYW4gdW5saW1pdGVkIG9yIGNvbnRyb2wgcmVnaW1lLiAKCmBSZWFyaW5nX3ZpYWwgKFIpYDogdGhlIHZpYWwgaW5kaXZpZHVhbCBmbGllcyBkZXZlbG9wZWQgd2l0aGluIG1heSBpbnRyb2R1Y2UgZnVydGhlciB2YXJpYXRpb24gaW50byBvdXIgcmVzcG9uc2UgdmFyaWFibGUuIExpa2UgYEJsb2NrYCB0aGlzIHZhcmlhYmxlIGNvbnRyb2xzIGZvciBtaWNyby1lbnZpcm9ubWVudGFsIHZhcmlhdGlvbi4KCiR+JAoKKipBY2NvdW50aW5nIGZvciBvdmVyLWRpc3BlcnNpb24qKgoKVGhlIGRhdGEgaXMgb3Zlci1kaXNwZXJzZWQgd2l0aCBzZXZlcmFsIGhpZ2hseSBpbmZsdWVudGlhbCAob3V0bGllcikgb2JzZXJ2YXRpb25zIHRoYXQgaGF2ZSBsYXJnZSBlZmZlY3RzIG9uIG91ciBwb3N0ZXJpb3IgcHJlZGljdGlvbi4gVG8gY29tYmF0IHRoaXMsIHdlIGZpdCBtb2RlbHMgZm9sbG93aW5nIHRoZSBgYmV0YWJpbm9taWFsYCBkaXN0cmlidXRpb24gZmFtaWx5LCBhcyB0aGlzIGlzIGJldHRlciBlcXVpcHBlZCB0byBkZWFsIHdpdGggZXh0cmVtZSB2YWx1ZXMgYXQgdGhlIHRhaWxzIGkuZS4gb3ZlcmRpc3BlcnNpb24uCgpIb3dldmVyLCB0aGUgYmV0YS1iaW5vbWlhbCBpcyBub3QgYSBuYXRpdmUgZmFtaWx5IGluIGBicm1zYCwgd2UgbmVlZCB0byBjcmVhdGUgdGhlIGRpc3RyaWJ1dGlvbiBmYW1pbHkgdXNpbmcgdGhlIGBjdXN0b21fZmFtaWx5KClgIGZ1bmN0aW9uLiBUaGUgY29kZSBiZWxvdyBpcyB0YWtlbiBkaXJlY3RseSBmcm9tIHRoZSBgYnJtc19jdXN0b21mYW1pbGllc2AgdmlnbmV0dGUsIHdoaWNoIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9icm1zL3ZpZ25ldHRlcy9icm1zX2N1c3RvbWZhbWlsaWVzLmh0bWwpLgoKYGBge3J9CmJldGFfYmlub21pYWwyIDwtIGN1c3RvbV9mYW1pbHkoCiAgImJldGFfYmlub21pYWwyIiwgZHBhcnMgPSBjKCJtdSIsICJwaGkiKSwKICBsaW5rcyA9IGMoImxvZ2l0IiwgImxvZyIpLCBsYiA9IGMoTkEsIDIpLCAKICAjIG5vdGUgdGhhdCB3ZSBzZXQgdGhlIGxvd2VyIGJvdW5kIHRvIDIsIGZvbGxvd2luZyBNY0VscmVhdGgsIHJhdGhlciB0aGFuIEJ1ZXJrbmVyLiBUaGlzIG1lYW5zIHRoYXQgdGhlIG1vc3QgY29uc2VydmF0aXZlIGVzdGltYXRlIGZvciBwaGkgd2UgZ2V0IGlzIGEgZmxhdCBleHBlY3RhdGlvbiBiZXR3ZWVuIDAgYW5kIDEKICB0eXBlID0gImludCIsIHZhcnMgPSAidmludDFbbl0iCikKCgpzdGFuX2Z1bnMgPC0gIgogIHJlYWwgYmV0YV9iaW5vbWlhbDJfbHBtZihpbnQgeSwgcmVhbCBtdSwgcmVhbCBwaGksIGludCBUKSB7CiAgICByZXR1cm4gYmV0YV9iaW5vbWlhbF9scG1mKHkgfCBULCBtdSAqIHBoaSwgKDEgLSBtdSkgKiBwaGkpOwogIH0KICBpbnQgYmV0YV9iaW5vbWlhbDJfcm5nKHJlYWwgbXUsIHJlYWwgcGhpLCBpbnQgVCkgewogICAgcmV0dXJuIGJldGFfYmlub21pYWxfcm5nKFQsIG11ICogcGhpLCAoMSAtIG11KSAqIHBoaSk7CiAgfQoiCgpzdGFudmFycyA8LSBzdGFudmFyKHNjb2RlID0gc3Rhbl9mdW5zLCBibG9jayA9ICJmdW5jdGlvbnMiKQoKYGBgCgokfiQKCiMgRmVtYWxlIGZpdG5lc3MKCiR+JAoKVG8gZXN0aW1hdGUgdGhlIGZpdG5lc3Mgb2YgZmVtYWxlcyBjYXJyeWluZyBlYWNoIG9mIHRoZSB0aHJlZSBhdXRvc29tZSB0eXBlcywgd2UgcGxhY2VkIHRocmVlIGV4cGVyaW1lbnRhbCBmZW1hbGVzIGludG8gYSB5ZWFzdGVkIHZpYWwgd2l0aCB0aHJlZSBmZW1hbGUgY29tcGV0aXRvcnMgdGhhdCBjYXJyaWVkIHRoZSBfYndfIG11dGF0aW9uLiBXZSB0aGVuIGludHJvZHVjZWQgc2l4IG1hbGVzIHRoYXQgYWxzbyBjYXJyaWVkIHRoZSBfYndfIG11dGF0aW9uLiBXZSBhbGxvd2VkIHRoZW0gdG8gbWF0ZSBhbmQgb3ZpcG9zaXQgZm9yIHRocmVlIGRheXMsIHRoZW4gcmVtb3ZlZCBhbGwgYWR1bHRzIGZyb20gdGhlIHZpYWwuIDEyIGRheXMgbGF0ZXIgd2UgY291bnRlZCBhbGwgb2YgdGhlIGFkdWx0IHByb2dlbnkgaW4gdGhlIHZpYWwgYW5kIHNjb3JlZCB0aGVtIGZvciBleWUtY29sb3VyLiBQcm9nZW55IHdpdGggcmVkIGV5ZXMgd2VyZSBwcm9kdWNlZCBieSB0aGUgZXhwZXJpbWVudGFsIGZlbWFsZXMgKCBfYndfIGlzIHJlY2Vzc2l2ZSkgYW5kIHByb2dlbnkgd2l0aCBicm93biBleWVzIHdlcmUgcHJvZHVjZWQgYnkgdGhlIGNvbXBldGl0b3IgZmVtYWxlcy4gV2UgY2FsY3VsYXRlZCBmaXRuZXNzIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHJlZCBleWVkIG9mZnNwcmluZyBpbiB0aGUgdmlhbC4gCgpXZSBwcmVzZW50IHRoZSBmaXhlZCBlZmZlY3RzIGZyb20gdGhlIG1vZGVsOgoKJH4kCgpgYGB7cn0KZmVtYWxlX2ZpdG5lc3NfbW9kZWwgPC0KICBicm0oVG90YWxfcmVkX29mZnNwcmluZyB8IHZpbnQoVG90YWxfb2Zmc3ByaW5nKSB+IDEgKyBJbmhlcml0YW5jZV90cmVhdG1lbnQgKyBCbG9jayArIEdGUCArICgxfFBvcHVsYXRpb24pICsgKDF8UmVhcmluZ192aWFsKSwKICAgICAgZGF0YSA9IGZlbWFsZV9maXRuZXNzLCBmYW1pbHkgPSBiZXRhX2Jpbm9taWFsMiwgCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gSW50ZXJjZXB0KSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksCiAgICAgIGl0ZXIgPSA0MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSwgbWF4X3RyZWVkZXB0aCA9IDEwKSwKICAgICAgc2VlZCA9IDIsIHN0YW52YXJzID0gc3RhbnZhcnMsIGZpbGUgPSAiRml0cy9mZW1hbGVfZml0bmVzcy5tb2RlbCIpCgpmaXhlZihmZW1hbGVfZml0bmVzc19tb2RlbCkgJT4lIAogIGthYmxlKGRpZ2l0cyA9IDMpICU+JSAKICBrYWJsZV9zdHlsaW5nKCkKCmBgYAoKV2UgbmVlZCB0byB3cml0ZSBzb21lIGFkZGl0aW9uYWwgY29kZSB0byBnZXQgc29tZSBwb3N0IHByb2Nlc3Npbmcgc3R1ZmYgaS5lLiBMT08gdG8gd29yay4gQ29kZSBjb3VydGVzeSBvZiB0aGUgYGJybXNfY3VzdG9tZmFtaWxpZXNgIHZpZ25ldHRlLCB3aGljaCBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYnJtcy92aWduZXR0ZXMvYnJtc19jdXN0b21mYW1pbGllcy5odG1sKS4KCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojIHdlIG5lZWQgdG8gd3JpdGUgc29tZSBhZGRpdGlvbmFsIGNvZGUgdG8gZ2V0IHNvbWUgcG9zdC1wcm9jZXNzaW5nIHN0dWZmIHRvIHdvcmsKCmV4cG9zZV9mdW5jdGlvbnMoZmVtYWxlX2ZpdG5lc3NfbW9kZWwsIHZlY3Rvcml6ZSA9IFRSVUUpCgoKbG9nX2xpa19iZXRhX2Jpbm9taWFsMiA8LSBmdW5jdGlvbihpLCBwcmVwKSB7CiAgbXUgPC0gYnJtczo6Z2V0X2RwYXIocHJlcCwgIm11IiwgaSA9IGkpCiAgcGhpIDwtIGJybXM6OmdldF9kcGFyKHByZXAsICJwaGkiLCBpID0gaSkKICB0cmlhbHMgPC0gcHJlcCRkYXRhJHZpbnQxW2ldCiAgeSA8LSBwcmVwJGRhdGEkWVtpXQogIGJldGFfYmlub21pYWwyX2xwbWYoeSwgbXUsIHBoaSwgdHJpYWxzKQp9Cgpwb3N0ZXJpb3JfcHJlZGljdF9iZXRhX2Jpbm9taWFsMiA8LSBmdW5jdGlvbihpLCBwcmVwLCAuLi4pIHsKICBtdSA8LSBicm1zOjpnZXRfZHBhcihwcmVwLCAibXUiLCBpID0gaSkKICBwaGkgPC0gYnJtczo6Z2V0X2RwYXIocHJlcCwgInBoaSIsIGkgPSBpKQogIHRyaWFscyA8LSBwcmVwJGRhdGEkdmludDFbaV0KICBiZXRhX2Jpbm9taWFsMl9ybmcobXUsIHBoaSwgdHJpYWxzKQp9Cgpwb3N0ZXJpb3JfZXByZWRfYmV0YV9iaW5vbWlhbDIgPC0gZnVuY3Rpb24ocHJlcCkgewogIG11IDwtIGJybXM6OmdldF9kcGFyKHByZXAsICJtdSIpCiAgdHJpYWxzIDwtIHByZXAkZGF0YSR2aW50MQogIHRyaWFscyA8LSBtYXRyaXgodHJpYWxzLCBucm93ID0gbnJvdyhtdSksIG5jb2wgPSBuY29sKG11KSwgYnlyb3cgPSBUUlVFKQogIG11ICogdHJpYWxzCn0KYGBgCgpSdW4gTE9PIHRvIHNlZSBpZiB3ZSd2ZSBlZmZlY3RpdmVseSBtb2RlbGxlZCBvdmVyIGRpc3BlcnNpb24uCgpgYGB7cn0KCmZlbWFsZV9maXRuZXNzX21vZGVsIDwtIGFkZF9jcml0ZXJpb24oZmVtYWxlX2ZpdG5lc3NfbW9kZWwsIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gIkZpdHMvZmVtYWxlX2ZpdG5lc3MubW9kZWwiKQoKbG9vKGZlbWFsZV9maXRuZXNzX21vZGVsKQoKYGBgCgpUaGUgYmV0YS1iaW5vbWlhbCBtb2RlbCBsb29rcyBnb29kLiBJdCByZXR1cm5zIG5vIHBvaW50cyB3aXRoIGhpZ2ggcGFyZXRvIGsgdmFsdWVzLgoKQ29uZHVjdCBhIHBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrIHRvIGNvbmZpcm0gb3VyIG1vZGVsIGlzIGRvaW5nIHdoYXQgd2Ugd2FudCBpdCB0by4KCmBgYHtyfQpwcF9jaGVjayhmZW1hbGVfZml0bmVzc19tb2RlbCwgdHlwZSA9ICJoaXN0IiwgbmRyYXdzID0gMTEsIGJpbndpZHRoID0gMTApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKVGhlIHBvc3RlcmlvciBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbiBtYXRjaGVzIG91ciByYXcgZGF0YSBxdWl0ZSB3ZWxsLCBpbmRpY2F0aW5nIHRoZSBtb2RlbCBpcyBmdW5jdGlvbmluZyBhcyB3ZSB3YW50ZWQuCgokfiQKCiMjIERlcml2ZSBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKCkdldCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBtb2RlbCBhbmQgcHJlc2VudCB0aGVtIGluIGEgVGFibGUKCmBgYHtyfQoKZHJhd3MgPC0gYXNfZHJhd3NfZGYoZmVtYWxlX2ZpdG5lc3NfbW9kZWwpCgpkcmF3c19mZW1hbGUgPC0KICBkcmF3cyAgJT4lIAogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQpLAogICAgICAgICBgTWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0luaGVyaXRhbmNlX3RyZWF0bWVudE1hbGVfbGltaXRlZCksCiAgICAgICAgIENvbnRyb2wgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSkgJT4lIAogIHNlbGVjdChgRmVtYWxlLWxpbWl0ZWRgLCBDb250cm9sLCBgTWFsZS1saW1pdGVkYCkgJT4lIAogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGBGZW1hbGUtbGltaXRlZGAsIENvbnRyb2wsIGBNYWxlLWxpbWl0ZWRgKSwKICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJJbmhlcml0YW5jZV90cmVhdG1lbnQiKSAlPiUgCiAgcmVuYW1lKHByb3BfZm9jYWxfb2Zmc3ByaW5nID0gdmFsdWUpICU+JSAKICBhcnJhbmdlKEluaGVyaXRhbmNlX3RyZWF0bWVudCkKCmRyYXdzX2RpZmYgPC0gZHJhd3MgICU+JSAKICBtdXRhdGUoYEZlbWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0luaGVyaXRhbmNlX3RyZWF0bWVudEZlbWFsZV9saW1pdGVkKSwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRNYWxlX2xpbWl0ZWQpLAogICAgICAgICBDb250cm9sID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCkpICU+JQogIG11dGF0ZShgRmVtYWxlIC0gQ29udHJvbGAgPSBgRmVtYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgYE1hbGUgLSBDb250cm9sYCA9IGBNYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgYEZlbWFsZSAtIE1hbGVgID0gYEZlbWFsZS1saW1pdGVkYCAtIGBNYWxlLWxpbWl0ZWRgKSAlPiUgCiAgc2VsZWN0KGBGZW1hbGUgLSBDb250cm9sYCwgYE1hbGUgLSBDb250cm9sYCwgYEZlbWFsZSAtIE1hbGVgKQoKICNkcmF3c19kaWZmICU+JSAKICAjIHN1bW1hcmlzZShgRXN0aW1hdGVkIHByb3AuIG9mIG9mZnNwcmluZyBwcm9kdWNlZGAgPSBtZWFuKGBNYWxlIC0gQ29udHJvbGApKjEwMCwKICAgIyAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGBNYWxlIC0gQ29udHJvbGAsIHByb2JzID0gMC4wMjUpICoxMDAsCiAgICAjICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYE1hbGUgLSBDb250cm9sYCwgcHJvYnMgPSAwLjk3NSkgKjEwMCkKCmRyYXdzX2ZlbWFsZSAlPiUgCiAgZ3JvdXBfYnkoSW5oZXJpdGFuY2VfdHJlYXRtZW50KSAlPiUgCiAgc3VtbWFyaXNlKGBFc3RpbWF0ZWQgcHJvcC4gb2Ygb2Zmc3ByaW5nIHByb2R1Y2VkYCA9IG1lYW4ocHJvcF9mb2NhbF9vZmZzcHJpbmcpLAogICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShwcm9wX2ZvY2FsX29mZnNwcmluZywgcHJvYnMgPSAwLjAyNSksCiAgICAgICAgICAgIGA5Ny41JWAgPSBxdWFudGlsZShwcm9wX2ZvY2FsX29mZnNwcmluZywgcHJvYnMgPSAwLjk3NSkpICU+JSAKICBwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZiwgcm91bmQgPSAzKQoKIyBub3cgZmluZCB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgY29udHJvbCBhbmQgdGhlIHNleC1saW1pdGVkIHRyZWF0bWVudHMKCiMgdGhlIGludl9sb2dpdF9zY2FsZWQoKSBmdW5jdGlvbiBjb252ZXJ0cyB0aGUgcG9zdGVyaW9yIGRyYXdzIG9udG8gdGhlIHJlc3BvbnNlIHNjYWxlIAoKcHJvcF90YWJsZV9mZW1hbGUgPC0KICBkcmF3cyAlPiUgCiAgbXV0YXRlKHBfY29udHJvbCA9ICBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSwKICAgICAgICAgcF9mZW1hbGUgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQgKyBiX0ludGVyY2VwdCksCiAgICAgICAgIHBfbWFsZSA9IGludl9sb2dpdF9zY2FsZWQoYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRNYWxlX2xpbWl0ZWQgKyBiX0ludGVyY2VwdCksCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZGAgPSBwX2ZlbWFsZSAvIHBfY29udHJvbCwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBwX21hbGUgLyBwX2NvbnRyb2wpICU+JSAKICBnYXRoZXIoa2V5ID0gYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAsIHZhbHVlID0gYCUgZGlmZmVyZW5jZWApICU+JSAKICBmaWx0ZXIoYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAgPT0gYygiRmVtYWxlLWxpbWl0ZWQiLCAiTWFsZS1saW1pdGVkIikpICU+JSAKICBncm91cF9ieShgZGlmZmVyZW5jZSBjb21wYXJpc29uYCkgICU+JSAKICBzdW1tYXJpc2UoYE1lYW4gcHJvcG9ydGlvbiBvZiBvZmZzcHJpbmcgcHJvZHVjZWQgcmVsYXRpdmUgdG8gY29udHJvbGAgID0gbWVhbihgJSBkaWZmZXJlbmNlYCksCiAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGAlIGRpZmZlcmVuY2VgLCBwcm9icyA9IDAuMDI1KSwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGAlIGRpZmZlcmVuY2VgLCBwcm9icyA9IDAuOTc1KSkgJT4lIAogIHJlbmFtZShgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCA9IGBkaWZmZXJlbmNlIGNvbXBhcmlzb25gKSAjJT4lIAojcGFuZGVyKHNwbGl0LmNlbGwgPSA0MCwgc3BsaXQudGFibGUgPSBJbmYsIHJvdW5kID0gMykKYGBgCgokfiQKCiMgTWFsZSBmaXRuZXNzCgokfiQKClRvIGVzdGltYXRlIHRoZSBmaXRuZXNzIG9mIG1hbGVzIGNhcnJ5aW5nIGVhY2ggb2YgdGhlIHRocmVlIGNocm9tb3NvbWUgdHlwZXMsIHdlIGNvbmR1Y3RlZCBhbiBleHBlcmltZW50IHZlcnkgc2ltaWxhciB0byB0aGUgZmVtYWxlIGZpdG5lc3MgYXNzYXkuIEhvd2V2ZXIsIGJlY2F1c2UgbWFsZSBmaXRuZXNzIGhhcyBzdHJvbmdlciBjb3ZhcmlhbmNlIHdpdGggZmVydGlsaXNhdGlvbiBldmVudHMgdGhhbiBkb2VzIGZlbWFsZSBmaXRuZXNzLCB3ZSBjb25kdWN0ZWQgdGhlIG1hbGUgZml0bmVzcyBhc3NheSB3aXRoIGEgMToyIHNleCByYXRpbyAoZmVtYWxlOm1hbGUpIHJhdGhlciB0aGFuIHRoZSAxOjEgcmF0aW8gdXNlZCBpbiB0aGUgZmVtYWxlIGFzc2F5LiBUaGlzIGluY3JlYXNlcyB0aGUgc3RyZW5ndGggb2Ygc2V4dWFsIHNlbGVjdGlvbiBhbmQgaXMgYSBtb3JlIGFwcHJvcHJpYXRlIHdheSB0byBleHBvc2UgZGlmZmVyZW5jZXMgaW4gZml0bmVzcyBiZXR3ZWVuIGdyb3VwcyBvZiBtYWxlcy4gQXMgd2l0aCB0aGUgZmVtYWxlcywgd2UgY2FsY3VsYXRlZCBmaXRuZXNzIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHJlZC1leWVkIG9mZnNwcmluZyBpbiB0aGUgdmlhbC4gCgpgYGB7cn0KCm1hbGVfZml0bmVzc19tb2RlbCA8LQogIGJybShUb3RhbF9yZWRfb2Zmc3ByaW5nIHwgdmludChUb3RhbF9vZmZzcHJpbmcpIH4gMSArIEluaGVyaXRhbmNlX3RyZWF0bWVudCArIEJsb2NrICsgR0ZQICsgKDF8UG9wdWxhdGlvbikgKyAoMXxSZWFyaW5nX3ZpYWwpLAogICAgICBkYXRhID0gbWFsZV9maXRuZXNzLCBmYW1pbHkgPSBiZXRhX2Jpbm9taWFsMiwgCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gSW50ZXJjZXB0KSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksCiAgICAgIGl0ZXIgPSA0MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSwgbWF4X3RyZWVkZXB0aCA9IDEwKSwKICAgICAgc2VlZCA9IDIsIHN0YW52YXJzID0gc3RhbnZhcnMsIGZpbGUgPSAiRml0cy9tYWxlX2ZpdG5lc3MubW9kZWwiKQoKCmZpeGVmKG1hbGVfZml0bmVzc19tb2RlbCkgJT4lIAogIGthYmxlKGRpZ2l0cyA9IDMpICU+JSAKICBrYWJsZV9zdHlsaW5nKCkKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KZXhwb3NlX2Z1bmN0aW9ucyhtYWxlX2ZpdG5lc3NfbW9kZWwsIHZlY3Rvcml6ZSA9IFRSVUUpCmBgYAoKUnVuIExPTyB0byBzZWUgaWYgd2UndmUgZWZmZWN0aXZlbHkgbW9kZWxsZWQgb3ZlciBkaXNwZXJzaW9uLgoKYGBge3J9CgptYWxlX2ZpdG5lc3NfbW9kZWwgPC0gYWRkX2NyaXRlcmlvbihtYWxlX2ZpdG5lc3NfbW9kZWwsIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gIkZpdHMvbWFsZV9maXRuZXNzLm1vZGVsIikKCmxvbyhtYWxlX2ZpdG5lc3NfbW9kZWwpCgpgYGAKClRoZXJlIGlzIG9uZSBwb2ludCBoYXZpbmcgYSBsYXJnZSBlZmZlY3Qgb24gdGhlIHBvc3Rlcmlvci4gVXBvbiBpbnNwZWN0aW9uLCB0aGlzIGRhdGEgcG9pbnQgaXMgbm90IGFuIHVucmVhc29uYWJsZSBvbmUgYW5kIHRoZXJlIGlzIG5vIGNhdXNlIHRvIHJlbW92ZSBpdCBmcm9tIHRoZSBkYXRhc2V0LiBJdCBhbHNvIGRvZXMgbm90IGNoYW5nZSB0aGUgY2F1c2FsIGVmZmVjdCBvZiBpbmhlcml0YW5jZSB0cmVhdG1lbnQgb24gbWFsZSBmaXRuZXNzLgoKQ29uZHVjdCB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2suLi4KCmBgYHtyfQpwcF9jaGVjayhtYWxlX2ZpdG5lc3NfbW9kZWwsIHR5cGUgPSAiaGlzdCIsIG5kcmF3cyA9IDExLCBiaW53aWR0aCA9IDEwKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIERlcml2ZSBlc3RpbWF0ZXMgZnJvbSBwb3N0ZXJpb3IKCkdldCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBtb2RlbCBhbmQgcHJlc2VudCB0aGVtIGluIGEgVGFibGUKCmBgYHtyfQoKIyBwcmVkaWN0aW9ucyBmb3IgYmxvY2sgMSwgd2l0aCBVQkkgR0ZQCgpuZXdfZGF0YSA8LSB0aWJibGUoSW5oZXJpdGFuY2VfdHJlYXRtZW50ID0gbWFsZV9maXRuZXNzJEluaGVyaXRhbmNlX3RyZWF0bWVudCkgJT4lIAogIGRpc3RpbmN0KEluaGVyaXRhbmNlX3RyZWF0bWVudCkgJT4lIAogIG11dGF0ZShQb3B1bGF0aW9uID0gMSwKICAgICAgICAgQmxvY2sgPSAxLAogICAgICAgICBSZWFyaW5nX3ZpYWwgPSAxLAogICAgICAgICBHRlAgPSAiVUJJIiwKICAgICAgICAgVG90YWxfb2Zmc3ByaW5nID0gMSkKCnByZWRpY3Rpb25zX21hbGUgPC0gZml0dGVkKG1hbGVfZml0bmVzc19tb2RlbCwgbmV3ZGF0YSA9IG5ld19kYXRhKQoKcHJlZGljdGlvbnNfbWFsZSA8LSBjYmluZChuZXdfZGF0YSwgcHJlZGljdGlvbnNfbWFsZSkKCgp0YWJsZTEgPC0KICBwcmVkaWN0aW9uc19tYWxlICU+JSAKICBzZWxlY3QoLWMoUG9wdWxhdGlvbiwgUmVhcmluZ192aWFsLCBHRlAsIFRvdGFsX29mZnNwcmluZykpICU+JQogIGFycmFuZ2UoQmxvY2spICU+JSAKICBwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZiwgcm91bmQgPSAzKQoKZHJhd3NfbSA8LSBhc19kcmF3c19kZihtYWxlX2ZpdG5lc3NfbW9kZWwpCgojIHByZWRpY3Rpb25zIGF2ZXJhZ2VkIG92ZXIgbWVkaWF0b3IgdmFyaWFibGVzCgpkcmF3c19tYWxlIDwtCiAgZHJhd3NfbSAgJT4lIAogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQpLAogICAgICAgICBgTWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0luaGVyaXRhbmNlX3RyZWF0bWVudE1hbGVfbGltaXRlZCksCiAgICAgICAgIENvbnRyb2wgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSkgJT4lIAogIHNlbGVjdChDb250cm9sLCBgRmVtYWxlLWxpbWl0ZWRgLCBgTWFsZS1saW1pdGVkYCkgJT4lIAogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKSwKICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJJbmhlcml0YW5jZV90cmVhdG1lbnQiKSAlPiUgCiAgcmVuYW1lKHByb3BfZm9jYWxfb2Zmc3ByaW5nID0gdmFsdWUpCgpkcmF3c19kaWZmX20gPC0gZHJhd3NfbSAlPiUgCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRGZW1hbGVfbGltaXRlZCksCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50TWFsZV9saW1pdGVkKSwKICAgICAgICAgQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpKSAlPiUKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkYCAtIENvbnRyb2wsCiAgICAgICAgIGBNYWxlIC0gQ29udHJvbGAgPSBgTWFsZS1saW1pdGVkYCAtIENvbnRyb2wsCiAgICAgICAgIGBGZW1hbGUgLSBNYWxlYCA9IGBGZW1hbGUtbGltaXRlZGAgLSBgTWFsZS1saW1pdGVkYCkgJT4lIAogIHNlbGVjdChgRmVtYWxlIC0gQ29udHJvbGAsIGBNYWxlIC0gQ29udHJvbGAsIGBGZW1hbGUgLSBNYWxlYCkKCiMgYWN0dWFsIFRhYmxlIDEKCmRyYXdzX21hbGUgJT4lIAogIGdyb3VwX2J5KEluaGVyaXRhbmNlX3RyZWF0bWVudCkgJT4lIAogIHN1bW1hcmlzZShgRXN0aW1hdGVkIHByb3AuIG9mIG9mZnNwcmluZyBzaXJlZGAgPSBtZWFuKHByb3BfZm9jYWxfb2Zmc3ByaW5nKSwKICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC4wMjUpLAogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC45NzUpKSAlPiUgCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSA0MCwgc3BsaXQudGFibGUgPSBJbmYsIHJvdW5kID0gMykKCiMgbm93IGZpbmQgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGNvbnRyb2wgYW5kIHRoZSBzZXgtbGltaXRlZCBFdm9sdXRpb25fdHJlYXRtZW50cwoKIyB0aGUgaW52X2xvZ2l0X3NjYWxlZCgpIGZ1bmN0aW9uIGNvbnZlcnRzIHRoZSBwb3N0ZXJpb3IgZHJhd3Mgb250byB0aGUgcmVzcG9uc2Ugc2NhbGUgCgpwcm9wX3RhYmxlX21hbGUgPC0gCiAgZHJhd3NfbSAlPiUgCiAgbXV0YXRlKHBfY29udHJvbCA9ICBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSwKICAgICAgICAgcF9mZW1hbGUgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW5oZXJpdGFuY2VfdHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQgKyBiX0ludGVyY2VwdCksCiAgICAgICAgIHBfbWFsZSA9IGludl9sb2dpdF9zY2FsZWQoYl9Jbmhlcml0YW5jZV90cmVhdG1lbnRNYWxlX2xpbWl0ZWQgKyBiX0ludGVyY2VwdCksCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZGAgPSBwX2ZlbWFsZSAvIHBfY29udHJvbCwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBwX21hbGUgLyBwX2NvbnRyb2wpICU+JSAKICBnYXRoZXIoa2V5ID0gYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAsIHZhbHVlID0gYCUgZGlmZmVyZW5jZWApICU+JSAKICBmaWx0ZXIoYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAgPT0gYygiRmVtYWxlLWxpbWl0ZWQiLCAiTWFsZS1saW1pdGVkIikpICU+JSAKICBncm91cF9ieShgZGlmZmVyZW5jZSBjb21wYXJpc29uYCkgICU+JSAKICBzdW1tYXJpc2UoYE1lYW4gcHJvcG9ydGlvbiBvZiBvZmZzcHJpbmcgc2lyZWQgcmVsYXRpdmUgdG8gY29udHJvbGAgID0gbWVhbihgJSBkaWZmZXJlbmNlYCksCiAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGAlIGRpZmZlcmVuY2VgLCBwcm9icyA9IDAuMDI1KSwKICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKGAlIGRpZmZlcmVuY2VgLCBwcm9icyA9IDAuOTc1KSkgJT4lIAogIHJlbmFtZShgSW5oZXJpdGFuY2UgdHJlYXRtZW50YCA9IGBkaWZmZXJlbmNlIGNvbXBhcmlzb25gKSAjJT4lIAogICNwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZiwgcm91bmQgPSAzKQpgYGAKCiMgQnVpbGRpbmcgRmlndXJlIDIKCmBgYHtyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04fQoKIyBmZW1hbGUgcGxvdHMKCmZfMSA8LQogIGRyYXdzX2ZlbWFsZSAlPiUgCiAgbXV0YXRlKEluaGVyaXRhbmNlX3RyZWF0bWVudCA9IGZjdF9yZWxldmVsKEluaGVyaXRhbmNlX3RyZWF0bWVudCwgIkZlbWFsZS1saW1pdGVkIiwgIkNvbnRyb2wiLCAiTWFsZS1saW1pdGVkIikpICU+JSAKICBnZ3Bsb3QoYWVzKEluaGVyaXRhbmNlX3RyZWF0bWVudCwgcHJvcF9mb2NhbF9vZmZzcHJpbmcpKSArIAogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IEluaGVyaXRhbmNlX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41KSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMykpICsKICBjb29yZF9mbGlwKCkgKwogIHhsYWIoIkluaGVyaXRhbmNlIHRyZWF0bWVudCIpICsKICB5bGFiKCJGZW1hbGUgZml0bmVzc1xuKHByb3AuIG9mZnNwcmluZyBwcm9kdWNlZCkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKZl8yIDwtCiAgZHJhd3NfZGlmZiAlPiUgCiAgZ2F0aGVyKGtleSA9IHBhcmFtZXRlciwgdmFsdWUgPSBgRml0bmVzcyBkaWZmZXJlbmNlYCkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAgIAoKICBnZ3Bsb3QoYWVzKHBhcmFtZXRlciwgYEZpdG5lc3MgZGlmZmVyZW5jZWApKSArIAogIHN0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsCiAgICAgICAgICAgICAgIHNsYWJfZmlsbCA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzFdLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBwb2ludF9maWxsID0gIndoaXRlIikgKyAjIHdpZHRoIGluZGljYXRlcyB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzOiBoZXJlIHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzCiAgY29vcmRfZmxpcCgpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsKICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLCAwLCAxKSkgKwogIHhsYWIoIlRyZWF0bWVudCBjb250cmFzdCIpICsKICB5bGFiKCJGZW1hbGUgZml0bmVzcyBkaWZmZXJlbmNlXG4ocHJvcC4gb2Zmc3ByaW5nIHByb2R1Y2VkKSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgojIG1hbGUgcGxvdHMKCmZfMyA8LQogIGRyYXdzX21hbGUgJT4lIAogIG11dGF0ZShJbmhlcml0YW5jZV90cmVhdG1lbnQgPSBmY3RfcmVsZXZlbChJbmhlcml0YW5jZV90cmVhdG1lbnQsICJGZW1hbGUtbGltaXRlZCIsICJDb250cm9sIiwgIk1hbGUtbGltaXRlZCIpKSAlPiUgCiAgZ2dwbG90KGFlcyhJbmhlcml0YW5jZV90cmVhdG1lbnQsIHByb3BfZm9jYWxfb2Zmc3ByaW5nKSkgKyAKICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gSW5oZXJpdGFuY2VfdHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUpICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDMpKSArCiAgY29vcmRfZmxpcCgpICsKICB4bGFiKCJJbmhlcml0YW5jZSB0cmVhdG1lbnQiKSArCiAgeWxhYigiTWFsZSBmaXRuZXNzXG4ocHJvcC4gb2Zmc3ByaW5nIHByb2R1Y2VkKSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgpmXzQgPC0KICBkcmF3c19kaWZmX20gJT4lCiAgZ2F0aGVyKGtleSA9IHBhcmFtZXRlciwgdmFsdWUgPSBgRml0bmVzcyBkaWZmZXJlbmNlYCkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBnZ3Bsb3QoYWVzKHBhcmFtZXRlciwgYEZpdG5lc3MgZGlmZmVyZW5jZWApKSArIAogIHN0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsCiAgICAgICAgICAgICAgIHNsYWJfZmlsbCA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzFdLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBwb2ludF9maWxsID0gIndoaXRlIikgKyAjIHdpZHRoIGluZGljYXRlcyB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzOiBoZXJlIHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSG9rdXNhaTMiLCAzKSkgKwogIGNvb3JkX2ZsaXAoKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLTAuMiwgLTAuMSwgMCwgMC4xLCAwLjIpKSArCiAgeGxhYigiVHJlYXRtZW50IGNvbnRyYXN0IikgKwogIHlsYWIoIk1hbGUgZml0bmVzcyBkaWZmZXJlbmNlXG4ocHJvcC4gb2Zmc3ByaW5nIHNpcmVkKSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgoKKGZfMSArIGZfMikgLyhmXzMgKyBmXzQpICsgCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpCgpgYGAKCioqRmlndXJlIDIqKjogKiphKiogc2hvd3MgdGhlIGVzdGltYXRlZCBkaXN0cmlidXRpb24gb2YgdGhlIG1lYW4gZm9yIGZlbWFsZSBmaXRuZXNzIGZvciBmbGllcyBjYXJyeWluZyBhdXRvc29tZXMgdGhhdCBoYWQgcHJldmlvdXNseSBleHBlcmllbmNlZCB1bmNvbnN0cmFpbmVkIGluaGVyaXRhbmNlIChjb250cm9sKSwgZmVtYWxlLWxpbWl0ZWQgaW5oZXJpdGFuY2Ugb3IgbWFsZS1saW1pdGVkIGluaGVyaXRhbmNlLiAqKmIqKiBzaG93cyB0aGUgZGlmZmVyZW5jZSBjb250cmFzdCBpbiBmZW1hbGUgZml0bmVzcyBiZXR3ZWVuIGVhY2ggb2YgdGhlIHRocmVlIGluaGVyaXRhbmNlIHRyZWF0bWVudHMuIFRoaXMgZGlmZmVyZW5jZSBpcyBvbiB0aGUgcHJvcG9ydGlvbiBzY2FsZSwgd2hlcmUgYSB2YWx1ZSBvZiAwLjEgaW5kaWNhdGVzIHRoYXQgZmVtYWxlcyBvZiBhIGdpdmVuIGluaGVyaXRhbmNlIHRyZWF0bWVudCBwcm9kdWNlIDEwIG1vcmUgb2Zmc3ByaW5nIHBlciBldmVyeSAxMDAgd2hlbiBjb2hhYml0aW5nIHdpdGggX2J3XyBjb21wZXRpdG9yIGZlbWFsZXMuICoqYyoqIGFuZCAqKmQqKiBkZXBpY3QgdGhlIHNhbWUgdGhpbmdzIGFzICoqYSoqIGFuZCAqKmIqKiwgZXhjZXB0IGZvciBtYWxlIGZpdG5lc3MuCgo=